#include <gtest/gtest.h>
#include "media_stream.h"
#include "muxer_mp4_writer.h"
#include "utils_log.h"
#include "utils_init.h"
#include "common_init.h"
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <unistd.h>

namespace El {
namespace Muxer {

class MP4WriterTest : public ::testing::Test {
protected:
    static void SetUpTestSuite()
    {
        // 初始化基础库
        nlohmann::json config;
        config["log_file"] = "app.log";
        El::Utils::base_init(config);

        // 初始化配置
        config.clear();
        config["general"] = "app_config";
        config["default"] = "default_config";
        El::Common::common_init(config);
    }

    void SetUp() override
    {
        writer_ = std::make_unique<MP4Writer>();
        testFilePath_ = "test_output.mp4";

        // 清理测试文件
        unlink(testFilePath_.c_str());
    }

    void TearDown() override
    {
        writer_->Close();
        // 清理测试文件
        // unlink(testFilePath_.c_str());
    }

    std::unique_ptr<MP4Writer> writer_;
    std::string testFilePath_;
};

TEST_F(MP4WriterTest, DISABLED_WriteVideoFrameTest)
{
    auto sourcePtr = Media::StreamSource::Create(0, 0);
    VideoEncFormat videoParams;
    videoParams.width = 1920;
    videoParams.height = 1080;
    videoParams.fps = 30;
    writer_->SetVideoParams(videoParams.width, videoParams.height, videoParams.fps);
    writer_->Open(testFilePath_);

    std::atomic<bool> shouldStop{false};
    std::condition_variable cv;
    std::mutex mtx;

    const uint64_t TARGET_DURATION_S = 20; // 目标录制时长20秒

    sourcePtr->Register([&](const Media::MediaFramePtr &frame) {
        if (frame->IsVideoFrame()) {

            writer_->WriteFrame(frame);

            // 检查录制时长
            uint64_t currentDuration = writer_->GetDuration();
            if (currentDuration >= TARGET_DURATION_S) {
                std::lock_guard<std::mutex> lock(mtx);
                shouldStop = true;
                cv.notify_one();
            }
        }
    });
    sourcePtr->Start();

    // 等待录制完成或超时
    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait_for(lock, std::chrono::seconds(21), [&]() { return shouldStop.load(); });
    }

    sourcePtr->Stop();

    // 验证录制时长
    uint64_t finalDuration = writer_->GetDuration();
    EL_INFO("Recording completed. Duration: {} us", finalDuration);

    EXPECT_GE(finalDuration, TARGET_DURATION_S);
    EXPECT_LE(finalDuration, TARGET_DURATION_S + 1); // 允许最多1秒的误差
    EXPECT_NE(writer_->GetFileSize(), 0);
}

TEST_F(MP4WriterTest, DISABLED_WriteAudioFrameTest)
{
    auto sourcePtr = Media::StreamSource::Create(0, 0);
    AudioEncFormat audioParams;
    audioParams.sampleRate = 48000;
    audioParams.channels = 1;
    audioParams.depth = 16;
    writer_->SetAudioParams(audioParams.sampleRate, audioParams.channels, audioParams.depth);
    writer_->Open(testFilePath_);

    std::atomic<bool> shouldStop{false};
    std::condition_variable cv;
    std::mutex mtx;

    const uint64_t TARGET_DURATION_S = 20; // 目标录制时长20秒

    sourcePtr->Register([&](const Media::MediaFramePtr &frame) {
        if (frame->IsAudioFrame()) {

            writer_->WriteFrame(frame);

            // 检查录制时长
            uint64_t currentDuration = writer_->GetDuration();
            if (currentDuration >= TARGET_DURATION_S) {
                std::lock_guard<std::mutex> lock(mtx);
                shouldStop = true;
                cv.notify_one();
            }
        }
    });
    sourcePtr->Start();
    // 等待录制完成或超时
    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait_for(lock, std::chrono::seconds(21), [&]() { return shouldStop.load(); });
    }

    sourcePtr->Stop();

    // 验证录制时长
    uint64_t finalDuration = writer_->GetDuration();
    EL_INFO("Recording completed. Duration: {} us", finalDuration);

    EXPECT_GE(finalDuration, TARGET_DURATION_S);
    EXPECT_LE(finalDuration, TARGET_DURATION_S + 1); // 允许最多1秒的误差
    EXPECT_NE(writer_->GetFileSize(), 0);
}

TEST_F(MP4WriterTest, MultipleFramesTest)
{
    auto sourcePtr = Media::StreamSource::Create(0, 0);
    VideoEncFormat videoParams;
    videoParams.width = 1920;
    videoParams.height = 1080;
    videoParams.fps = 30;
    writer_->SetVideoParams(videoParams.width, videoParams.height, videoParams.fps);

    AudioEncFormat audioParams;
    audioParams.sampleRate = 48000;
    audioParams.channels = 1;
    audioParams.depth = 16;
    writer_->SetAudioParams(audioParams.sampleRate, audioParams.channels, audioParams.depth);

    writer_->Open(testFilePath_);

    std::atomic<bool> shouldStop{false};
    std::condition_variable cv;
    std::mutex mtx;

    const uint64_t TARGET_DURATION_S = 20; // 目标录制时长20秒

    sourcePtr->Register([&](const Media::MediaFramePtr &frame) {
        writer_->WriteFrame(frame);
        // 检查录制时长
        uint64_t currentDuration = writer_->GetDuration();
        if (currentDuration >= TARGET_DURATION_S) {
            std::lock_guard<std::mutex> lock(mtx);
            shouldStop = true;
            cv.notify_one();
        }
    });
    sourcePtr->Start();

    // 等待录制完成或超时
    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait_for(lock, std::chrono::seconds(21), [&]() { return shouldStop.load(); });
    }

    sourcePtr->Stop();

    // 验证录制时长
    uint64_t finalDuration = writer_->GetDuration();
    EL_INFO("Recording completed. Duration: {} us", finalDuration);

    EXPECT_GE(finalDuration, TARGET_DURATION_S);
    EXPECT_LE(finalDuration, TARGET_DURATION_S + 1); // 允许最多1秒的误差
    EXPECT_NE(writer_->GetFileSize(), 0);
}

} // namespace Muxer
} // namespace El